/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-4-17 下午1:38 Created by sky
 */
package com.jade.bss.base.customer.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.jade.bss.base.BssException;
import com.jade.bss.base.customer.UserMapping;
import com.jade.bss.base.customer.UserMappingDao;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.sql.SqlUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;

/**
 * 采用JPA方式实现的用户映射数据访问接口。
 *
 * @author sky
 * @version 1.0 13-4-17 下午1:38
 */
@Named ("bss_userMappingDao")
public class JpaUserMappingDao
        implements UserMappingDao
{
    @PersistenceContext (unitName = "default")
    protected EntityManager em;

    public void setEntityManager(EntityManager em)
    {
        this.em = em;
    }

    public void addMapping(UserMapping userMapping)
    {
        em.persist(userMapping);
    }

    @Cacheable (value = "bss.customer.um.g", key = "#customerId + '[%GRP%]' + #appCode")
    public UserMapping getMapping(long customerId, String appCode)
    {
        return em.find(UserMapping.class, new UserMapping(customerId, appCode));
    }

    @SuppressWarnings ("unchecked")
    @Cacheable (value = "bss.customer.um.gu", key = "#appCode + '[%GRP%]' + #userId")
    public UserMapping getMapping(String appCode, String userId)
    {
        String sql = SQL_SELECT + " WHERE appCode=:appCode AND userId=:userId";
        Query query = em.createQuery(sql);
        query.setParameter("appCode", appCode);
        query.setParameter("userId", userId);
        List<UserMapping> mappings = query.getResultList();
        if (mappings.isEmpty()) {
            return null;
        }
        else {
            return mappings.get(0);
        }
    }

    @SuppressWarnings ("unchecked")
    @Cacheable (value = "bss.customer.um.g", key = "#customerId + '[%GRP%]' + 'all'")
    public Map<String, String> getUserMap(long customerId)
    {
        String sql = SQL_SELECT + " WHERE customerId=:customerId";
        Query query = em.createQuery(sql);
        query.setParameter("customerId", customerId);
        List<UserMapping> mappings = query.getResultList();
        Map<String, String> userMap = new HashMap<String, String>();
        for (UserMapping mapping : mappings) {
            userMap.put(mapping.getAppCode(), mapping.getUserId());
        }
        return userMap;
    }

    @Caching (evict = {@CacheEvict (value = "bss.customer.um.g", key = "#customerId + '[%GRP%]'"),
            @CacheEvict (value = "bss.customer.um.gu", key = "#appCode + '[%GRP%]'")})
    public void removeMapping(long customerId, String appCode)
            throws BssException
    {
        UserMapping mapping = em.find(UserMapping.class, new UserMapping(customerId, appCode));
        if (mapping != null) {
            em.remove(mapping);
        }
    }

    @Caching (evict = {@CacheEvict (value = "bss.customer.um.g", key = "#customerId + '[%GRP%]'"),
            @CacheEvict (value = "bss.customer.um.gu", allEntries = true)})
    public void removeMapping(long customerId)
    {
        String sql = SQL_DELETE + " WHERE customerId=:customerId";
        Query query = em.createQuery(sql);
        query.setParameter("customerId", customerId);
        query.executeUpdate();
    }

    public List<UserMapping> listMapping(Criteria criteria)
    {
        return SqlUtils.sqlQueryWithoutCount(SQL_SELECT, em, criteria);
    }

    protected static final String SQL_SELECT = "SELECT mapping FROM com.jade.bss.base.customer.UserMapping mapping";
    protected static final String SQL_DELETE = "DELETE FROM com.jade.bss.base.customer.UserMapping";
}
